//
//  NSArray+HACShield.m
//  HACShield
//
//  Created by Chengjie on 2019/5/22.
//

#import "NSArray+HACShield.h"
#import "NSObject+HACSwizzling.h"

@implementation NSArray (HACShield)

/**
 NSArray *commonArr = [NSArray alloc];
 NSArray *arr01 = [commonArr init];
 NSArray *arr02 = [commonArr initWithObjects:@"1", nil];
 NSArray *arr03 = [commonArr initWithObjects:@"1", @"2", nil];
 NSArray *arr04 = [commonArr initWithObjects:@"1", @"2", @"3", nil];
 NSLog(@"commonArr: %s", object_getClassName(commonArr));
 NSLog(@"arr01: %s", object_getClassName(arr01));
 NSLog(@"arr02: %s", object_getClassName(arr02));
 NSLog(@"arr03: %s", object_getClassName(arr03));
 NSLog(@"arr04: %s", object_getClassName(arr04));
 
 ---------------------
 2019-05-23 13:20:00.002174+0800 HACShield[16548:3585328] commonArr: __NSPlaceholderArray
 2019-05-23 13:20:00.002345+0800 HACShield[16548:3585328] arr01: __NSArray0
 2019-05-23 13:20:00.002426+0800 HACShield[16548:3585328] arr02: __NSSingleObjectArrayI
 2019-05-23 13:20:00.002489+0800 HACShield[16548:3585328] arr03: __NSArrayI
 2019-05-23 13:20:00.002551+0800 HACShield[16548:3585328] arr04: __NSArrayI
 ---------------------
 
 */
+ (void)load {
    static dispatch_once_t onceToken;
    dispatch_once(&onceToken, ^{
        // 取值越界
        SEL sel_obj_at_index = @selector(objectAtIndex:);
        hac_swizzleInstanceMethod(hac_getClass(@"__NSA", @"rray0"), sel_obj_at_index, @selector(hac_array0_objectAtIndex:));
        hac_swizzleInstanceMethod(hac_getClass(@"__NSS", @"ingleObjectArrayI"), sel_obj_at_index, @selector(hac_singleObjectArrayI_objectAtIndex:));
        hac_swizzleInstanceMethod(hac_getClass(@"__NSA", @"rrayI"), sel_obj_at_index, @selector(hac_objectAtIndex:));
        // *** 👇 以下内容可以不需要，因为方法不存在已经被 HACCrashSavior 拯救了
        // 添加出错
        SEL sel_add_obj = @selector(addObject:);
        SEL hac_sel_add_obj = @selector(hac_addObject:);
        hac_swizzleInstanceMethod(hac_getClass(@"__NSA", @"rray0"), sel_add_obj, hac_sel_add_obj);
        hac_swizzleInstanceMethod(hac_getClass(@"__NSS", @"ingleObjectArrayI"), sel_add_obj, hac_sel_add_obj);
        hac_swizzleInstanceMethod(hac_getClass(@"__NSA", @"rrayI"), sel_add_obj, hac_sel_add_obj);
        // 插入
        SEL sel_insert_obj = @selector(insertObject:atIndex:);
        SEL hac_sel_insert_obj = @selector(hac_insertObject:atIndex:);
        hac_swizzleInstanceMethod(hac_getClass(@"__NSA", @"rray0"), sel_insert_obj, hac_sel_insert_obj);
        hac_swizzleInstanceMethod(hac_getClass(@"__NSS", @"ingleObjectArrayI"), sel_insert_obj, hac_sel_insert_obj);
        hac_swizzleInstanceMethod(hac_getClass(@"__NSA", @"rrayI"), sel_insert_obj, hac_sel_insert_obj);
        // 移除
        SEL sel_remove_obj = @selector(removeObjectAtIndex:);
        SEL hac_sel_remove_obj = @selector(hac_removeObjectAtIndex:);
        hac_swizzleInstanceMethod(hac_getClass(@"__NSA", @"rray0"), sel_remove_obj, hac_sel_remove_obj);
        hac_swizzleInstanceMethod(hac_getClass(@"__NSS", @"ingleObjectArrayI"), sel_remove_obj, hac_sel_remove_obj);
        hac_swizzleInstanceMethod(hac_getClass(@"__NSA", @"rrayI"), sel_remove_obj, hac_sel_remove_obj);
        // 替换
        SEL sel_replace_obj = @selector(replaceObjectAtIndex:withObject:);
        SEL hac_sel_replace_obj = @selector(hac_replaceObjectAtIndex:withObject:);
        hac_swizzleInstanceMethod(hac_getClass(@"__NSA", @"rray0"), sel_replace_obj, hac_sel_replace_obj);
        hac_swizzleInstanceMethod(hac_getClass(@"__NSS", @"ingleObjectArrayI"), sel_replace_obj, hac_sel_replace_obj);
        hac_swizzleInstanceMethod(hac_getClass(@"__NSA", @"rrayI"), sel_replace_obj, hac_sel_replace_obj);
        // 交换
        SEL sel_exchange_obj = @selector(exchangeObjectAtIndex:withObjectAtIndex:);
        SEL hac_sel_exchange_obj = @selector(hac_exchangeObjectAtIndex:withObjectAtIndex:);
        hac_swizzleInstanceMethod(hac_getClass(@"__NSA", @"rray0"), sel_exchange_obj, hac_sel_exchange_obj);
        hac_swizzleInstanceMethod(hac_getClass(@"__NSS", @"ingleObjectArrayI"), sel_exchange_obj, hac_sel_exchange_obj);
        hac_swizzleInstanceMethod(hac_getClass(@"__NSA", @"rrayI"), sel_exchange_obj, hac_sel_exchange_obj);
    });
}

#pragma mark - 取值越界防护

- (id)hac_objectAtIndex:(NSUInteger)index {
    if (index < 0 || index >= self.count) {
        return nil;
    }
    return [self hac_objectAtIndex:index];
}

- (id)hac_array0_objectAtIndex:(NSUInteger)index {
    return nil;
}

- (id)hac_singleObjectArrayI_objectAtIndex:(NSUInteger)index {
    if (index < 0 || index >= 1) {
        return nil;
    }
    return [self hac_singleObjectArrayI_objectAtIndex:index];
}

#pragma mark - 方法不存在出错

- (void)hac_addObject:(id)object {}

- (void)hac_insertObject:(id)anObject atIndex:(NSUInteger)index {}

- (void)hac_removeObjectAtIndex:(NSUInteger)index {}

- (void)hac_replaceObjectAtIndex:(NSUInteger)index withObject:(id)anObject {}

- (void)hac_exchangeObjectAtIndex:(NSUInteger)idx1 withObjectAtIndex:(NSUInteger)idx2 {}


@end
